/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.app.service.order.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shop.cereshop.app.dao.product.CereSkuMemberRealInfoDAO;
import com.shop.cereshop.app.dao.shop.CerePlatformShopDAO;
import com.shop.cereshop.app.page.cart.CartSku;
import com.shop.cereshop.app.page.cart.ShopCart;
import com.shop.cereshop.app.page.product.ProductCoupon;
import com.shop.cereshop.app.page.settlement.Distribution;
import com.shop.cereshop.app.page.settlement.SimpleSettlement;
import com.shop.cereshop.app.page.settlement.SettlementShop;
import com.shop.cereshop.app.param.settlement.SimpleSettlementParam;
import com.shop.cereshop.app.service.buyer.CereBuyerReceiveService;
import com.shop.cereshop.app.service.buyer.CereBuyerShopCouponService;
import com.shop.cereshop.app.service.cart.CereShopCartService;
import com.shop.cereshop.app.service.logistics.CereOrderLogisticsService;
import com.shop.cereshop.app.service.order.SimpleSettlementService;
import com.shop.cereshop.app.utils.DistributionUtil;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.buyer.CereBuyerShopCoupon;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.logistics.CereOrderLogistics;
import com.shop.cereshop.commons.domain.shop.CerePlatformShop;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 简化版结算服务实现类
 */
@Slf4j
@Service
public class SimpleSettlementServiceImpl implements SimpleSettlementService {

    @Autowired
    private CereShopCartService cereShopCartService;

    @Autowired
    private CereBuyerReceiveService cereBuyerReceiveService;

    @Autowired
    private CereBuyerShopCouponService cereBuyerShopCouponService;

    @Autowired
    private CereSkuMemberRealInfoDAO cereSkuMemberRealInfoDAO;

    @Autowired
    private CerePlatformShopDAO cerePlatformShopDAO;

    @Autowired
    private CereOrderLogisticsService cereOrderLogisticsService;

    @Override
    public SimpleSettlement getSettlement(SimpleSettlementParam param, CereBuyerUser user) throws CoBusinessException {
        SimpleSettlement settlement = new SimpleSettlement();

        // 1. 处理收货地址
        if (EmptyUtils.isEmpty(param.getReceiveId())) {
            // 查询默认地址
            settlement.setReceive(cereBuyerReceiveService.findlatelyReceiveByUserId(user.getBuyerUserId()));
        } else {
            settlement.setReceive(cereBuyerReceiveService.findById(param.getReceiveId()));
        }

        // 2. 根据商品类型从购物车查询选中的商品
        List<ShopCart> shopCarts = cereShopCartService.getCart(null, null, user, param.getType());

        if (EmptyUtils.isEmpty(shopCarts)) {
            // 如果没有选中的商品，返回空结果
            settlement.setInvalidShops(new ArrayList<>());
            return settlement;
        }

        // 3. 收集选中的商品信息
        List<Long> skuIdList = new ArrayList<>();
        Map<Long, Integer> skuNumberMap = new HashMap<>(); // skuId -> 数量
        Map<Long, Long> skuShopIdMap = new HashMap<>(); // skuId -> shopId
        Map<Long, List<CartSku>> shopSkuMap = new HashMap<>(); // shopId -> 商品列表
        Set<Long> shopIdSet = new HashSet<>();

        for (ShopCart shopCart : shopCarts) {
            if (!EmptyUtils.isEmpty(shopCart.getSkus())) {
                for (CartSku sku : shopCart.getSkus()) {
                    if (true) {
                        skuIdList.add(sku.getSkuId());
                        skuNumberMap.put(sku.getSkuId(), sku.getNumber());
                        skuShopIdMap.put(sku.getSkuId(), shopCart.getShopId());
                        shopIdSet.add(shopCart.getShopId());

                        shopSkuMap.computeIfAbsent(shopCart.getShopId(), k -> new ArrayList<>()).add(sku);
                    }
                }
            }
        }

        if (skuIdList.isEmpty()) {
            settlement.setInvalidShops(new ArrayList<>());
            return settlement;
        }

        // 4. 从实时信息表查询商品价格信息
        Long memberLevelId = 0L;
        if (user != null && user.getMemberLevelId() != null) {
            memberLevelId = user.getMemberLevelId();
        }
        List<CartSku> realInfoList = cereSkuMemberRealInfoDAO.findSkuListBySkuIdList(skuIdList, memberLevelId);
        Map<Long, CartSku> realInfoMap = realInfoList.stream()
                .collect(Collectors.toMap(CartSku::getSkuId, Function.identity()));

        // 5. 查询店铺信息
        List<CerePlatformShop> shopList = cerePlatformShopDAO.selectList(
                Wrappers.<CerePlatformShop>lambdaQuery().in(CerePlatformShop::getShopId, shopIdSet));
        Map<Long, CerePlatformShop> shopMap = shopList.stream()
                .collect(Collectors.toMap(CerePlatformShop::getShopId, Function.identity()));

        // 6. 构建结算店铺信息，验证商品是否能下单
        List<SettlementShop> shopSettlementList = new ArrayList<>();
        List<SettlementShop> invalidShops = new ArrayList<>();
        AtomicBoolean hasInvalidProduct = new AtomicBoolean(false);
        List<Long> productIdList = new ArrayList<>();
        Map<Long, List<CartSku>> validShopSkuMap = new HashMap<>(); // 用于运费计算

        for (Long shopId : shopIdSet) {
            CerePlatformShop shop = shopMap.get(shopId);
            if (shop == null) {
                continue;
            }

            SettlementShop settlementShop = new SettlementShop();
            settlementShop.setShopId(shopId);
            settlementShop.setShopName(shop.getShopName());
            settlementShop.setShopLogo(shop.getShopLogo());
            settlementShop.setShopAdress(shop.getShopAdress());

            List<CartSku> validSkus = new ArrayList<>();
            List<CartSku> invalidSkus = new ArrayList<>();
            BigDecimal total = BigDecimal.ZERO;

            List<CartSku> shopSkus = shopSkuMap.get(shopId);
            if (!EmptyUtils.isEmpty(shopSkus)) {
                for (CartSku cartSku : shopSkus) {
                    CartSku realInfo = realInfoMap.get(cartSku.getSkuId());
                    if (realInfo == null) {
                        // 商品不存在或已下架
                        hasInvalidProduct.set(true);
                        invalidSkus.add(cartSku);
                        continue;
                    }

                    // 设置商品信息
                    cartSku.setPrice(realInfo.getPrice());
                    cartSku.setOriginalPrice(realInfo.getOriginalPrice());
                    cartSku.setStockNumber(realInfo.getStockNumber());
                    cartSku.setNumber(skuNumberMap.get(cartSku.getSkuId()));
                    cartSku.setSelected(IntegerEnum.YES.getCode());

                    // 校验库存
                    if (cartSku.getNumber() > cartSku.getStockNumber()) {
                        hasInvalidProduct.set(true);
                        invalidSkus.add(cartSku);
                        continue;
                    }

                    // 计算商品总价
                    BigDecimal itemTotal = cartSku.getPrice().multiply(new BigDecimal(cartSku.getNumber()));
                    cartSku.setTotal(itemTotal);
                    total = total.add(itemTotal);

                    if (!productIdList.contains(cartSku.getProductId())) {
                        productIdList.add(cartSku.getProductId());
                    }

                    validSkus.add(cartSku);
                }
            }

            settlementShop.setSkus(validSkus);
            settlementShop.setNumber(validSkus.stream().mapToInt(CartSku::getNumber).sum());
            settlementShop.setTotal(total.setScale(2, BigDecimal.ROUND_HALF_UP));

            if (!invalidSkus.isEmpty()) {
                SettlementShop invalidShop = new SettlementShop();
                invalidShop.setShopId(shopId);
                invalidShop.setSkus(invalidSkus);
                invalidShop.setNumber(invalidSkus.stream().mapToInt(CartSku::getNumber).sum());
                invalidShops.add(invalidShop);
            }

            if (!validSkus.isEmpty()) {
                shopSettlementList.add(settlementShop);
                validShopSkuMap.put(shopId, validSkus);
            }
        }

        settlement.setInvalidShops(invalidShops);

        // 7. 计算运费
        if (!shopSettlementList.isEmpty() && settlement.getReceive() != null) {
            Distribution distribution = calculateDistribution(param.getType(), shopSettlementList, validShopSkuMap, settlement.getReceive());
            settlement.setDistribution(distribution);
        } else {
            // 如果没有收货地址或没有有效商品，设置默认运费为0
            Distribution defaultDistribution = new Distribution();
            defaultDistribution.setDistributionPrice(BigDecimal.ZERO);
            defaultDistribution.setDistributionName("全国包邮");
            settlement.setDistribution(defaultDistribution);
        }

        // 8. 处理优惠券逻辑
        if (!shopSettlementList.isEmpty() && !productIdList.isEmpty()) {
            // 计算订单总金额（所有店铺的总和）
            BigDecimal totalPrice = shopSettlementList.stream()
                    .map(SettlementShop::getTotal)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 如果用户选择了优惠券，验证并使用
            if (param.getCouponId() != null) {
                CereBuyerShopCoupon buyerCoupon = cereBuyerShopCouponService.findById(param.getCouponId());
                if (buyerCoupon == null) {
                    settlement.setCouponMessage("优惠券不存在");
                } else if (!buyerCoupon.getBuyerUserId().equals(user.getBuyerUserId())) {
                    settlement.setCouponMessage("优惠券不属于当前用户");
                } else if (!IntegerEnum.COUPON_HAVE.getCode().equals(buyerCoupon.getState())) {
                    if (IntegerEnum.COUPON_USE.getCode().equals(buyerCoupon.getState())) {
                        settlement.setCouponMessage("优惠券已使用");
                    } else if (IntegerEnum.COUPON_OVERDUE.getCode().equals(buyerCoupon.getState())) {
                        settlement.setCouponMessage("优惠券已过期");
                    } else {
                        settlement.setCouponMessage("优惠券不可用");
                    }
                } else {
                    // 验证优惠券是否可用
                    String nowTime = TimeUtils.yyMMddHHmmss();
                    if (buyerCoupon.getStartTime() != null && nowTime.compareTo(buyerCoupon.getStartTime()) < 0) {
                        settlement.setCouponMessage("优惠券尚未生效");
                    } else if (buyerCoupon.getEndTime() != null && nowTime.compareTo(buyerCoupon.getEndTime()) > 0) {
                        settlement.setCouponMessage("优惠券已过期");
                    } else if (buyerCoupon.getFullMoney() != null && totalPrice.compareTo(buyerCoupon.getFullMoney()) < 0) {
                        settlement.setCouponMessage("订单金额未达到优惠券使用门槛");
                    } else {
                        // 验证优惠券适用商品
                        // 查询可用优惠券列表来获取优惠券详细信息
                        List<ProductCoupon> availableCoupons = cereBuyerShopCouponService.findCouponMatchCondition(
                                user.getBuyerUserId(), totalPrice, productIdList);

                        ProductCoupon usedCoupon = null;
                        for (ProductCoupon coupon : availableCoupons) {
                            if (coupon.getId().equals(param.getCouponId())) {
                                usedCoupon = coupon;
                                break;
                            }
                        }

                        if (usedCoupon == null) {
                            settlement.setCouponMessage("优惠券不适用于当前商品");
                        } else {
                            // 计算优惠金额
                            BigDecimal discountAmount = calculateCouponDiscount(usedCoupon, totalPrice);
                            if (discountAmount.compareTo(BigDecimal.ZERO) <= 0) {
                                settlement.setCouponMessage("优惠券不满足使用条件");
                            }
                            // 注意：不再返回usedCoupon和shops，只返回couponMessage提示信息
                        }
                    }
                }
            }
        }

        if (hasInvalidProduct.get()) {
            throw new CoBusinessException(CoReturnFormat.HAVE_INVALID_PRODUCT, settlement);
        }

        return settlement;
    }

    /**
     * 计算运费
     * @param type 商品售卖类型 1-到店核销 2-电商购 3-同城送
     * @param shopSettlementList 店铺结算列表
     * @param validShopSkuMap 有效商品Map（shopId -> 商品列表）
     * @param receive 收货地址
     * @return 运费信息
     */
    private Distribution calculateDistribution(Integer type, List<SettlementShop> shopSettlementList,
                                               Map<Long, List<CartSku>> validShopSkuMap,
                                               com.shop.cereshop.commons.domain.buyer.CereBuyerReceive receive) {
        Distribution distribution = new Distribution();
        
        if (type == null) {
            // 默认免邮费
            distribution.setDistributionPrice(BigDecimal.ZERO);
            distribution.setDistributionName("全国包邮");
            return distribution;
        }
        
        if (Integer.valueOf(1).equals(type)) {
            // type=1：到店核销，直接免邮费
            distribution.setDistributionPrice(BigDecimal.ZERO);
            distribution.setDistributionName("到店核销免邮");
            return distribution;
        } else if (Integer.valueOf(2).equals(type)) {
            // type=2：电商购，按照运费配置计算运费
            if (shopSettlementList.isEmpty()) {
                distribution.setDistributionPrice(BigDecimal.ZERO);
                distribution.setDistributionName("全国包邮");
                return distribution;
            }
            
            // 取第一个店铺计算运费（根据业务规则，同一类型下只会有一个店铺）
            SettlementShop firstShop = shopSettlementList.get(0);
            List<CartSku> skus = validShopSkuMap.get(firstShop.getShopId());
            if (EmptyUtils.isEmpty(skus)) {
                distribution.setDistributionPrice(BigDecimal.ZERO);
                distribution.setDistributionName("全国包邮");
                return distribution;
            }
            
            // 查询店铺物流方案
            List<CereOrderLogistics> logistics = cereOrderLogisticsService.findLogistics(firstShop.getShopId());
            if (EmptyUtils.isEmpty(logistics)) {
                distribution.setDistributionPrice(BigDecimal.ZERO);
                distribution.setDistributionName("全国包邮");
                return distribution;
            }
            
            // 构建商品数量Map
            Map<Long, Integer> buyNumberMap = skus.stream()
                    .collect(Collectors.toMap(CartSku::getSkuId, CartSku::getNumber));
            
            // 使用DistributionUtil计算运费
            Distribution calculatedDistribution = DistributionUtil.getDistribution(logistics, receive, buyNumberMap, skus);
            if (calculatedDistribution != null) {
                return calculatedDistribution;
            } else {
                // 如果没有匹配的物流方案，默认包邮
                distribution.setDistributionPrice(BigDecimal.ZERO);
                distribution.setDistributionName("全国包邮");
                return distribution;
            }
        } else if (Integer.valueOf(3).equals(type)) {
            // type=3：同城送，需要调用三方接口计算运费
            // TODO: 调用三方接口计算同城送运费
            // 目前默认返回1元
            distribution.setDistributionPrice(new BigDecimal("1.00"));
            distribution.setDistributionName("同城配送");
            distribution.setLogisticsId(-1L);
            return distribution;
        } else {
            // 其他类型，默认免邮费
            distribution.setDistributionPrice(BigDecimal.ZERO);
            distribution.setDistributionName("全国包邮");
            return distribution;
        }
    }

    /**
     * 计算优惠券的优惠金额
     * @param coupon 优惠券
     * @param totalPrice 订单总金额
     * @return 优惠金额
     */
    private BigDecimal calculateCouponDiscount(ProductCoupon coupon, BigDecimal totalPrice) {
        if (coupon == null || totalPrice == null || totalPrice.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }

        // 检查是否满足使用门槛
        BigDecimal threshold = coupon.getFullMoney();
        if (threshold != null && threshold.compareTo(BigDecimal.ZERO) > 0) {
            if (totalPrice.compareTo(threshold) < 0) {
                return BigDecimal.ZERO;
            }
        }

        // 根据优惠券类型计算优惠金额
        Integer couponType = coupon.getCouponType();
        if (IntegerEnum.COUPON_TYPE_REDUTION.getCode().equals(couponType)) {
            // 满减券：直接返回减的金额
            BigDecimal reduceMoney = coupon.getReduceMoney();
            if (reduceMoney != null && reduceMoney.compareTo(BigDecimal.ZERO) > 0) {
                return reduceMoney.min(totalPrice);
            }
        } else if (IntegerEnum.COUPON_TYPE_DISCOUNT.getCode().equals(couponType)) {
            // 折扣券：计算折扣金额
            // 折扣券的折扣率存储在 reduceMoney 字段中（如8表示8折）
            BigDecimal discountRate = coupon.getReduceMoney();
            if (discountRate != null && discountRate.compareTo(BigDecimal.ZERO) > 0
                    && discountRate.compareTo(BigDecimal.TEN) <= 0) {
                // 计算折扣金额 = 总金额 * (10 - 折扣率) / 10
                BigDecimal discount = totalPrice.multiply(BigDecimal.TEN.subtract(discountRate))
                        .divide(BigDecimal.TEN, 2, BigDecimal.ROUND_HALF_UP);
                return discount;
            }
        }

        return BigDecimal.ZERO;
    }
}
